package com.yidin.util;

import java.util.List;
import java.util.Locale;
import com.yidin.lsc.BaseActivity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;

/**
 * 定位服务类
 * 
 * @author cola
 * 
 */
public class GPSPoint {
	static final String TAG = "GPSPoint";
	private LocationInfo LI;
	private static final int MINTIME = 2000;
	private static final int MININSTANCE = 2;
	public Location location;// 当前位置的经纬度
	/**
	 * 经度
	 */
	public String lat = "0";
	/**
	 * 纬度
	 */
	public String lng = "0";
	/**
	 * 当前地址
	 */
	public String address = "";

	/**
	 * Gps 定位
	 */
	private LocationManager locationManager;
	/**
	 * 基站定位
	 */
	private LocationManager networkLocationManager;
	private BaseActivity bs;
	private String provider;
	public static GPSPoint self;

	public static GPSPoint getInstance(BaseActivity bs) {
		if (self == null) {
			self = new GPSPoint();
			self.bs = bs;
			self.self = self;
			return self;
		} else
			return self;
	}

	/**
	 * 更新要显示数据的界面句柄
	 * 
	 * @param bs
	 */
	public void setBaseActivity(BaseActivity bs) {
		this.bs = bs;
		self.LI = new LocationInfo();
	}

	public void initialization() {
		// 得到GPS设备的访问
		locationManager = (LocationManager) bs
				.getSystemService(Context.LOCATION_SERVICE);
		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(true);
		criteria.setPowerRequirement(Criteria.POWER_LOW);
		provider = locationManager.getBestProvider(criteria, true);

		// 基站定位
		networkLocationManager = (LocationManager) bs
				.getSystemService(Context.LOCATION_SERVICE);
	}

	public void getGPSPoint(Context context) {
		if (provider == null) {
			Toast.makeText(context, "请打开gps设置，程序需要位置服务", Toast.LENGTH_LONG)
					.show();
			return;
		}
		// provider = LocationManager.NETWORK_PROVIDER;
		else {
			locationManager.requestLocationUpdates(provider, 2000, 10,
					locationlistener);
		}
//		networkLocationManager.requestLocationUpdates(
//				LocationManager.NETWORK_PROVIDER, MINTIME, MININSTANCE,
//				locationlistener);

		location = locationManager.getLastKnownLocation(provider);
		// 侦听GPS状态，主要是捕获到的各个卫星的状态
		if (location == null)
			location = networkLocationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		new Thread(getAddressName).start();
		// updateNewLocation(location);
	}

	private LocationListener locationlistener = new LocationListener() {
		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderEnabled(String provider) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onProviderDisabled(String provider) {
			updateNewLocation(null);
		}

		@Override
		public void onLocationChanged(Location loca) {
			location = loca;
			new Thread(getAddressName).start();
			// updateNewLocation(location);
		}
	};

	public String updateNewLocation(Location location) {
		this.location = location;
		String locatioStr = "";
		this.lat = location.getLatitude() + "";
		this.lng = location.getLongitude() + "";
		if(lat.equals("")) lat = "0";
		if(lng.equals("")) lng = "0";

		List<Address> cityName = getAddressbyGeoPoint(location);
		if (cityName != null && cityName.size() > 0) {
			Address address = cityName.get(0);
			self.LI.city = address.getLocality();
			self.LI.city = self.LI.city.substring(0, self.LI.city.indexOf("市"));
			locatioStr = address.getAddressLine(1) + address.getAddressLine(2);// getFeatureName();//getAdminArea();//省级;//getLocality();//市级;//.toString();
		} else
			return "";
		return locatioStr;
	}

	/**
	 * 获取地址信息
	 * 
	 * @param location
	 * @return
	 */
	private List<Address> getAddressbyGeoPoint(Location location) {
		List<Address> result = null;
		// 先将 Location 转换为 GeoPoint
		try {
			if (location != null) {
				// 获取 Geocoder ，通过 Geocoder 就可以拿到地址信息
				Geocoder gc = new Geocoder(bs, Locale.getDefault());
				result = gc.getFromLocation(location.getLatitude(),
						location.getLongitude(), 1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * Gps状态监听
	 */
	private GpsStatus.Listener gpsStatusListener = new GpsStatus.Listener() {
		@Override
		public void onGpsStatusChanged(int event) {
			// TODO Auto-generated method stub
			GpsStatus gpsStatus = locationManager.getGpsStatus(null);
			switch (event) {
			case GpsStatus.GPS_EVENT_FIRST_FIX: {
				// 第一次定位时间UTC gps可用
				int i = gpsStatus.getTimeToFirstFix();
				Log.v(TAG, "GPS is usable");
				break;
			}
			}
		}

	};

	public Location getLoaction() {
		Location location = locationManager.getLastKnownLocation(provider);
		if (location == null)
			location = networkLocationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
		return location;
	}

	/**
	 * 判断是否开启GPS
	 */
	public static void openGPSSettings(Activity self) {
		LocationManager alm = (LocationManager) self
				.getSystemService(Context.LOCATION_SERVICE);
		if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
			// Toast.makeText(self, "GPS模块正常", Toast.LENGTH_SHORT).show();
			return;
		}
		Toast.makeText(self, "请开启GPS！", Toast.LENGTH_SHORT).show();
		Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);// ACTION_SECURITY_SETTINGS);
		self.startActivityForResult(intent, 0); // 此为设置完成后返回到获取界面
	}

	public void destoryLocationManager() {
		Log.d(TAG, "destoryLocationManager");
		locationManager.removeUpdates(locationlistener);
		networkLocationManager.removeUpdates(locationlistener);
	}

	/**
	 * 获取位置信息
	 */
	private final int MSG_VIEW_ADDRESSNAME = 0x10;
	/**
	 * 线程中获取费时的地址信息
	 */
	Runnable getAddressName = new Runnable() {
		@Override
		public void run() {
			String addressName = "";
			while (true) {
				if (location == null) {
					location = locationManager.getLastKnownLocation(provider);
					// 侦听GPS状态，主要是捕获到的各个卫星的状态
					if (location == null)
						location = networkLocationManager
								.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
					Log.d(TAG, "无法获取位置信息");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					continue;
				}
				addressName = updateNewLocation(location);
				Log.d(TAG, "获取地址: " + addressName);
				if (!"".equals(addressName)) {
					break;
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			Message msg = new Message();
			msg.what = MSG_VIEW_ADDRESSNAME;
			msg.obj = addressName;
			mHandler.sendMessage(msg);
		}
	};

	public interface GpsInfo {
		public void getGpsInfo(LocationInfo info);
	}

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_VIEW_ADDRESSNAME:// 更新地理信息
				self.LI.Location = (String) msg.obj;
				// bs.refresh(Task.TASK_UPDATE_LOCATION, self.LI);
				break;
			}
		}
	};

	/**
	 * 位置信息
	 * 
	 * @author cola
	 * 
	 */
	public class LocationInfo {
		/**
		 * 位置详细信息
		 */
		public String Location;
		/**
		 * 当前定位城市
		 */
		public String city;

		public String lat;
		public String lng;
	}
	
	private final static double EARTH_RADIUS = 6378.137;
	private static double rad(double d)
	{
	   return d * Math.PI / 180.0;
	}
	
	/**
	 * 通过两点计算两点间的距离
	 * @param lat1
	 * @param lng1
	 * @param lat2
	 * @param lng2
	 * @return （单位：千米）
	 */
	public static double GetDistance(double lat1, double lng1, double lat2,
			double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
				+ Math.cos(radLat1) * Math.cos(radLat2)
				* Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = Math.round(s * 10000) / 10000;
		return s;
	}
}
